package com.zmn.oms.admin.controller.work.modify;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.github.jsonzou.jmockdata.JMockData;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.zmn.base.channel.common.dro.ChannelDRO;
import com.zmn.base.channel.common.query.ChannelQuery;
import com.zmn.base.common.data.common.dro.company.CompanyDRO;
import com.zmn.base.plat.engine.common.constant.CompanyConsts;
import com.zmn.base.product.common.dto.product.erp.ProductGroupDRO;
import com.zmn.base.product.dubbo.interfaces.product.foreign.ProductGroupForeignListRemoteService;
import com.zmn.biz.abnormal.dubbo.interfaces.AbnormalListRemoteService;
import com.zmn.biz.complain.dubbo.interfaces.complain.ChsComplainApiListRemoteService;
import com.zmn.common.constant.GlobalConsts;
import com.zmn.common.dictionary.KvModel;
import com.zmn.common.dto2.ResponseDTO;
import com.zmn.common.utils.date.DateUtil;
import com.zmn.common.utils.number.NumberUtil;
import com.zmn.common.utils.reflect.BeanMapper;
import com.zmn.common.utils.string.StringUtil;
import com.zmn.oms.admin.controller.OmsBaseController;
import com.zmn.oms.business.interfaces.base.BaseCodeService;
import com.zmn.oms.business.interfaces.callpop.CallRecordBService;
import com.zmn.oms.business.interfaces.factorypart.FactoryPartBService;
import com.zmn.oms.business.interfaces.invoice.OrderInvoiceBService;
import com.zmn.oms.business.interfaces.masterphoto.OrderPhotoBService;
import com.zmn.oms.business.interfaces.nonstandard.OrderNonstandardBService;
import com.zmn.oms.business.interfaces.orderattachment.OrderAttachmentBService;
import com.zmn.oms.business.interfaces.remark.OrderRemarkBService;
import com.zmn.oms.business.interfaces.track.OrderTrackBService;
import com.zmn.oms.common.constant.EmbedUrlConsts;
import com.zmn.oms.common.constant.OrderConsts;
import com.zmn.oms.common.constant.OrderFactoryPartConsts;
import com.zmn.oms.common.constant.SystemConsts;
import com.zmn.oms.common.dto.OmsOperator;
import com.zmn.oms.common.dto.ResultDTO;
import com.zmn.oms.common.exception.OmsBaseException;
import com.zmn.oms.common.utils.MathUtil;
import com.zmn.oms.common.vo.KVDict;
import com.zmn.oms.model.dto.graborder.GrabConfigDTO;
import com.zmn.oms.model.dto.invoice.OrderInvoiceDTO;
import com.zmn.oms.model.dto.track.OrderTrackDTO;
import com.zmn.oms.model.dto.work.modify.*;
import com.zmn.oms.model.dto.work.modify.must.OrderWorkGrabDTO;
import com.zmn.oms.model.dto.work.modify.other.ZsPartReimburseGroupDTO;
import com.zmn.oms.model.dto.work.modify.other.ZsRemarkDTO;
import com.zmn.oms.model.entity.factory.OrderFactory;
import com.zmn.oms.model.entity.nonstandard.OrderNonstandard;
import com.zmn.oms.model.entity.work.OrderWork;
import com.zmn.oms.model.vo.factorypart.NewPartVO;
import com.zmn.oms.model.vo.factorypart.UsedPartVO;
import com.zmn.oms.model.vo.part.PartReimburseVO;
import com.zmn.oms.model.vo.track.OrderTrackVO;
import com.zmn.oms.model.vo.work.NonstandardDetailVO;
import com.zmn.oms.model.vo.work.NonstandardVO;
import com.zmn.oms.model.vo.work.OperatePermissionVO;
import com.zmn.oms.model.vo.work.modify.OrderPostVO;
import com.zmn.oms.model.vo.work.modify.ZsOrderWarrantyVO;
import com.zmn.oms.services.interfaces.callrecord.OrderCallRecordService;
import com.zmn.oms.services.interfaces.detail.OrderDetailService;
import com.zmn.oms.services.interfaces.factory.OrderFactoryService;
import com.zmn.oms.services.interfaces.invoice.OrderInvoiceService;
import com.zmn.oms.services.interfaces.nonstandard.OrderNonstandardService;
import com.zmn.oms.services.interfaces.order.OrderExtendService;
import com.zmn.oms.services.interfaces.work.OrderWorkService;
import com.zmn.oms.zmn.business.interfaces.part.ZsOrderPartBService;
import com.zmn.oms.zmn.business.interfaces.work.OrderWorkGrabBService;
import com.zmn.oms.zmn.business.interfaces.work.OrderWorkOrderPostBService;
import com.zmn.oms.zmn.business.interfaces.work.ZsOrderWorkBService;
import com.zmn.oms.zmn.business.interfaces.work.ZsOrderWorkOperatePermissionBService;
import com.zmn.oms.zmn.business.interfaces.work.autoflow.WorkFlowContextBService;
import com.zmn.oms.zmn.business.interfaces.work.customwork.ZsCustomWorkBService;
import com.zmn.oms.zmn.normal.business.interfaces.order.ZsNormalOrderBService;
import com.zmn.oms.zmn.normal.business.interfaces.part.ZsNormalOrderPartBService;
import com.zmn.oms.zmn.normal.business.interfaces.warranty.ZsNormalOrderWarrantyBService;
import com.zmn.scm2.common.model.dro.scm.purchase.freight.ImgPassDRO;
import com.zmn.scm2.dubbo.interfaces.scm.purchase.freight.PurchaseFreightListRemoteService;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.Reference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 类描述：工单列表操作controller
 *
 * @author lujia
 * @date 2018/11/07 16:32
 */
@Controller
@RequestMapping("/work/modify")
public class WorkModifyOtherController extends OmsBaseController {

    private Logger logger = LoggerFactory.getLogger(WorkModifyOtherController.class);

    @Autowired
    ZsCustomWorkBService zsCustomWorkBService;
    @Autowired
    ZsOrderWorkBService zsOrderWorkBService;
    @Autowired
    OrderRemarkBService orderRemarkBService;
    @Autowired
    OrderExtendService orderExtendService;
    @Autowired
    OrderWorkService orderWorkService;
    @Autowired
    OrderDetailService orderDetailService;
    @Autowired
    ZsNormalOrderWarrantyBService zsNormalOrderWarrantyBService;
    @Autowired
    ZsNormalOrderPartBService zsNormalOrderPartBService;
    @Autowired
    ZsNormalOrderBService zsNormalOrderBService;
    @Autowired
    OrderInvoiceService orderInvoiceService;
    @Autowired
    OrderInvoiceBService orderInvoiceBService;
    @Autowired
    OrderTrackBService orderTrackBService;
    @Autowired
    BaseCodeService baseCodeService;
    @Autowired
    ZsOrderWorkOperatePermissionBService orderWorkOperatePermissionBService;
    @Autowired
    ZsOrderPartBService zsOrderPartBService;
    @Autowired
    OrderPhotoBService orderPhotoBService;
    @Autowired
    OrderCallRecordService orderCallRecordService;
    @Autowired
    OrderNonstandardService orderNonstandardService;
    @Autowired
    OrderNonstandardBService orderNonstandardBService;
    @Autowired
    OrderWorkOrderPostBService orderWorkOrderPostBService;
    @Autowired
    FactoryPartBService factoryPartBService;
    @Autowired
    OrderFactoryService orderFactoryService;
    @Autowired
    OrderAttachmentBService orderAttachmentBService;
    @Autowired
    CallRecordBService callRecordBService;
    @Autowired
    OrderWorkGrabBService orderWorkGrabBService;

    @Autowired
    private WorkFlowContextBService workFlowContextBService;

    @DubboReference(version = com.zmn.ums.dubbo.utils.DubboConsts.INTERFACE_VERSION, check = false)
    AbnormalListRemoteService abnormalListRemoteService;
    @DubboReference(version = com.zmn.ums.dubbo.utils.DubboConsts.INTERFACE_VERSION, check = false)
    ChsComplainApiListRemoteService chsComplainApiListRemoteService;
    @DubboReference(version = com.zmn.scm2.dubbo.interfaces.utils.DubboConsts.INTERFACE_VERSION, check = false)
    PurchaseFreightListRemoteService purchaseFreightListRemoteService;
    @DubboReference(version = com.zmn.ums.dubbo.utils.DubboConsts.INTERFACE_VERSION, check = false)
    ProductGroupForeignListRemoteService productGroupForeignListRemoteService;


    /**
     * 备注
     */
    @RequestMapping(value = "/remark")
    public ModelAndView remark(Long orderId, Long workId) {
        OrderWork orderWork = orderWorkService.findOrderWorkByKey(orderId, workId);
        ModelAndView mv = new ModelAndView("work/modify/remark");
        mv.addObject("orderWork", orderWork);

        // 是否支持厂商备注 (查询渠道是否开通商家账号或者是厂商账户)
        /*ResponseDTO<FactoryBaseDRO> factoryRemote = factoryListRemoteService.getFactoryByChannelId(orderWork.getChannelId());
        logger.debug("是否支持厂商备注：orderId:{},responseDTO:{}", orderWork.getChannelId(), JSONObject.toJSONString(factoryRemote));*/
        boolean supportFactoryRemark = false;
        // 子公司权限不可见厂商备注 一步维修不可见厂商备注
        supportFactoryRemark = supportFactoryRemark && !isBranchCompany() && !Objects.equals(orderWork.getPlatWork(), GlobalConsts.PLAT_MARK_SAAS);

        // 是否支持服务商备注 (厂商保内订单) 平台：言而有信、一步维修可见
        boolean supportServiceProviderRemark = Objects.equals(orderWork.getSourceType(), OrderConsts.ORDER_SOURCE_TYPE_FACTORY)
                && Objects.equals(orderWork.getBizType(), com.zmn.consts.GlobalConsts.BIZ_TYPE_F)
                && (Objects.equals(orderWork.getPlatWork(), GlobalConsts.PLAT_MARK_YEYX) || Objects.equals(orderWork.getPlatWork(), GlobalConsts.PLAT_MARK_SAAS));

        mv.addObject("orderWork", orderWork);
        mv.addObject("supportFactoryRemark", supportFactoryRemark);
        mv.addObject("supportServiceProviderRemark", supportServiceProviderRemark);

        return mv;
    }

    /**
     * 保存备注
     */
    @PostMapping(value = "/save/remark")
    @ResponseBody
    public ResultDTO saveRemark(@RequestBody ZsRemarkDTO dto) {
        // 内部备注
        if (StringUtil.isNotBlank(dto.getRemark())) {
            zsNormalOrderBService.saveWorkRemark(dto);
        }

        // 工程师备注
        if (StringUtil.isNotBlank(dto.getMasterRemark())) {
            zsNormalOrderBService.saveMasterRemark(dto);
        }

        // 商家备注
        if (StringUtil.isNotBlank(dto.getFactoryRemark())) {
            zsNormalOrderBService.saveFactoryRemark(dto);
        }

        // 服务商备注
        if (StringUtil.isNotBlank(dto.getServiceProviderRemark())) {
            zsNormalOrderBService.saveServiceProviderRemark(dto);
        }

        return ResultDTO.success();
    }

    /**
     * 改渠道
     */
    @GetMapping(value = "/channel")
    public ModelAndView channel(Long orderId, Long workId) {
        OrderWork orderWork = orderWorkService.findOrderWorkByKey(orderId, workId);
        Integer channelId = orderWork.getChannelId();
        // 加载：订单所在下单平台&非厂商渠道&渠道参数是：允许修改渠道的二级渠道
        List<KVDict> channelList = new ArrayList<>();
        ChannelQuery channelDIO = new ChannelQuery();
        channelDIO.setPlat(orderWork.getPlat());
        channelDIO.setContractModel(orderWork.getBizModeSource());
        channelDIO.setRank(2);
        channelDIO.setChannelTypes(Lists.newArrayList(1, 2, 4, 5, 6));
        channelDIO.setStatus(GlobalConsts.YES);
        ResponseDTO<List<ChannelDRO>> channelDRO = channelListRemoteService.listByQuery(channelDIO);
        if (channelDRO.getData() == null) {
            channelList =  Lists.newArrayList();
        }else {
            List<KVDict> list = Lists.newArrayListWithCapacity(channelDRO.getData().size());
            channelDRO.getData().forEach((item) -> list.add(KVDict.<Integer>builder().value(item.getChannelId()).text(item.getName()).build()));
            channelList.addAll(list);
        }
        ModelAndView mv = new ModelAndView("work/modify/channel");
        mv.addObject("channelList", channelList);
        mv.addObject("channelId", channelId);
        mv.addObject("orderWork", orderWork);
        return mv;
    }

    /**
     * 保存改渠道
     */
    @PostMapping(value = "/save/channel")
    @ResponseBody
    public ResultDTO saveChannel(@RequestBody ChannelUpdateDTO channelUpdateDTO) throws OmsBaseException {
        OperatePermissionVO operatePermission = orderWorkOperatePermissionBService.getOperatePermission(channelUpdateDTO.getOrderId(), channelUpdateDTO.getWorkId(), OrderConsts.ORDER_OP_TYPE_UPDATE_CHANNEL);
        if (!operatePermission.getCanOperate()) {
            return ResultDTO.fail(operatePermission.getMsg());
        }

        zsCustomWorkBService.updateChannel(channelUpdateDTO);
        return ResultDTO.success();
    }

    /**
     * 保单
     */
    @GetMapping(value = "/warranty")
    public ModelAndView warranty(Long orderId, Long workId, Integer operateId) throws OmsBaseException {
        ZsOrderWarrantyVO vo = zsNormalOrderWarrantyBService.findOrderWarrantyVo(orderId, workId);
        ModelAndView mv = new ModelAndView("work/modify/warranty");

        ZsOrderWarrantyVO orderWarrantyVO = Optional.ofNullable(vo).orElse(JMockData.mock(ZsOrderWarrantyVO.class));
        mv.addObject("orderWarrantyVO", orderWarrantyVO);
        mv.addObject("operatorId", operateId);
        return mv;
    }

    /**
     * 保存保单
     */
    @PostMapping(value = "/save/warranty")
    @ResponseBody
    public ResultDTO saveWarranty(@RequestBody OrderWarrantyDTO orderWarrantyDTO) throws OmsBaseException {
        OperatePermissionVO operatePermission = orderWorkOperatePermissionBService.getOperatePermission(orderWarrantyDTO.getOrderId(), orderWarrantyDTO.getWorkId(), OrderConsts.ORDER_OP_TYPE_WARRANTY);
        if (!operatePermission.getCanOperate()) {
            return ResultDTO.fail(operatePermission.getMsg());
        }

        zsNormalOrderWarrantyBService.updateWarranty(orderWarrantyDTO);
        return ResultDTO.success();
    }

    /**
     * 删除保单项
     *
     * @return
     */
    @PostMapping(value = "/delete/warranty")
    @ResponseBody
    public ResultDTO deleteWarranty(@RequestBody OrderWarrantyDTO orderWarrantyDTO) {
        OperatePermissionVO operatePermission = orderWorkOperatePermissionBService.getOperatePermission(orderWarrantyDTO.getOrderId(), orderWarrantyDTO.getOrderId(), OrderConsts.ORDER_OP_TYPE_WARRANTY);
        if (!operatePermission.getCanOperate()) {
            return ResultDTO.fail(operatePermission.getMsg());
        }

        zsNormalOrderWarrantyBService.deleteWarranty(orderWarrantyDTO);
        return ResultDTO.success();
    }

    /**
     * 配件报销
     */
    @GetMapping(value = "/part/reimburse")
    public ModelAndView partReimburse(Long orderId, Long workId) throws OmsBaseException {
        OrderWork orderWork = orderWorkService.findOrderWorkByKey(orderId, workId);
        // 查询出当前工单下所有需要报销的配件
        List<PartReimburseVO> reimburseVOList = zsNormalOrderPartBService.listPartReimburseByOrderId(orderId);

        ResponseDTO<List<ImgPassDRO>> imgPassResponseDTO = purchaseFreightListRemoteService.listImgPass(orderId);
        logger.info("配件报销获取发票：[{}]", JSONObject.toJSONString(imgPassResponseDTO));
        if (!imgPassResponseDTO.isSuccess()) {
            logger.error("dubbo interface fail!");
        }

        List<ImgPassDRO> items = imgPassResponseDTO.getData();
        Map<String, ImgPassDRO> imgPassMap = items.stream().collect(Collectors.toMap(ImgPassDRO::getFreightReimburseId, e -> e));

        // 每组【配件报销】记录
        Map<String, List<PartReimburseVO>> partReimburseMap;

        // 计算出每组【配件报销】记录所需要的【报销】总金额
        Map<String, Integer> reimburseVOAmountMap = Maps.newHashMap();

        // 是否显示不予报销选项
        Map<String, Boolean> unAllowReimburseMap = Maps.newHashMap();

        // 是否有【配件报销】的提交记录
        boolean has = reimburseVOList.stream().anyMatch(e -> e.getApplyId() != null);

        if (has) {
            partReimburseMap = reimburseVOList.stream().collect(Collectors.groupingBy(PartReimburseVO::getApplyId));
            partReimburseMap.forEach((key, partReimburseVOList) -> {
                Integer partReimburseAmount = partReimburseVOList.stream().mapToInt(part -> MathUtil.amountMultiplyNumber(part.getPrice(),
                        part.getNumber())).sum();
                reimburseVOAmountMap.put(key, partReimburseAmount);
                unAllowReimburseMap.put(key, false);
            });
        } else {
            // 当从来没有提交过【报销记录】时 默认所有配件为一组。
            partReimburseMap = Maps.newHashMap();
            // 报销总金额
            Integer reimburseVOAmount = reimburseVOList.stream().mapToInt(part -> MathUtil.amountMultiplyNumber(part.getPrice(),
                    part.getNumber())).sum();

            partReimburseMap.put("0", reimburseVOList);
            reimburseVOAmountMap.put("0", reimburseVOAmount);
        }

        // 获取配件转换
        //Map<Integer, ZsPartUnitConversionVO> partUnitConversion = zsOrderPartBService.getPartUnitConversion();

        // 标准报销金额
        Integer standardReimbursementAmount = null;

        // 非直营，非家修匠做最低金额限制报销
        if (!Objects.equals(orderWork.getCompanyId(), com.zmn.oms.common.constant.CompanyConsts.ZMN_JXJ_COMPANY_ID)
                && Objects.equals(orderWork.getManageCompanyType(), CompanyConsts.COMPANY_TYPE_SERVICE_NOT_OCO)) {
            ResponseDTO<List<ProductGroupDRO>> groupResponseDTO = productGroupForeignListRemoteService.listByGroupIdsAndStatus(Lists.newArrayList(orderWork.getServProductGroupId()), GlobalConsts.YES);
            if (!groupResponseDTO.isSuccess() || CollectionUtils.isEmpty(groupResponseDTO.getData())) {
                throw new OmsBaseException("无法获取订单产品组信息，请联系技术人员稍后重试");
            }

            ProductGroupDRO groupDRO = groupResponseDTO.getData().get(0);
            standardReimbursementAmount = groupDRO.getReimbursement();

            Boolean isUnAllowReimburse = false;
            int totalAmount = reimburseVOList.stream().mapToInt(part ->
                    MathUtil.amountMultiplyNumber(part.getPrice(), part.getNumber())).sum();
            if (totalAmount <= Optional.ofNullable(standardReimbursementAmount).orElse(0)) {
                isUnAllowReimburse = true;
            }
            Boolean finalIsUnAllowReimburse = isUnAllowReimburse;
            reimburseVOAmountMap.forEach((key, reimburseAmount) -> {
                unAllowReimburseMap.put(key, finalIsUnAllowReimburse);
            });
        }

        ModelAndView mv = new ModelAndView("work/modify/partreimburse");
        mv.addObject("orderWork", orderWork);
        mv.addObject("reimburseCount", reimburseVOList.size());
        mv.addObject("reimburseMap", partReimburseMap);
        mv.addObject("imgPassMap", imgPassMap);
        mv.addObject("reimburseVOAmountMap", reimburseVOAmountMap);
        mv.addObject("unAllowReimburseMap", unAllowReimburseMap);
        mv.addObject("standardReimbursementAmount", standardReimbursementAmount);
//        mv.addObject("conversionMap", partUnitConversion);

        return mv;
    }

    /**
     * 保存配件报销
     *
     * @author liudi
     * @since: 2022/3/3 21:34
     * @param zsPartReimburseGroupDTO
     * @return
     */
    @PostMapping(value = "/save/part/reimburse")
    @ResponseBody
    public ResultDTO savePartReimburse(@RequestBody ZsPartReimburseGroupDTO zsPartReimburseGroupDTO) {
        OperatePermissionVO operatePermission = orderWorkOperatePermissionBService.getOperatePermission(zsPartReimburseGroupDTO.getOrderId(), zsPartReimburseGroupDTO.getWorkId(), OrderConsts.ORDER_OP_TYPE_PART_REIMBURSE);
        if (!operatePermission.getCanOperate()) {
            return ResultDTO.fail(operatePermission.getMsg());
        }

        OrderWork dbOrderWork = orderWorkService.findOrderWorkByKey(zsPartReimburseGroupDTO.getOrderId(), zsPartReimburseGroupDTO.getWorkId());
        OperatePermissionVO existsSCMToAuditPartsOPV = orderWorkOperatePermissionBService.existsSCMToAuditParts(zsPartReimburseGroupDTO.getOrderId(), dbOrderWork.getType());
        if (!existsSCMToAuditPartsOPV.getCanOperate()) {
            return ResultDTO.fail(existsSCMToAuditPartsOPV.getMsg());
        }

        try {
            zsNormalOrderBService.savePartReimburse(zsPartReimburseGroupDTO);

            // 自动收单
            // workFlowContextBService.asyncAutoFlow(zsPartReimburseGroupDTO.getOrderId(), zsPartReimburseGroupDTO.getWorkId());
        } catch (OmsBaseException e) {
            logger.error("配件报销单价修改失败：[{}]",e.getMessage());
            return ResultDTO.fail(e.getMessage());
        }
        return ResultDTO.success();
    }

    /**
     * 开发票
     */
    @RequestMapping(value = "/invoice")
    public ModelAndView invoice(Long orderId, Long workId) throws OmsBaseException{
        ModelAndView mv = new ModelAndView("work/modify/invoice");

        mv.addObject("orderId", String.valueOf(orderId));
        mv.addObject("workId", String.valueOf(workId));
        return mv;
    }

    /**
     * 发票反馈
     */
    @RequestMapping(value = "/invoiceFeedBack")
    public ModelAndView invoiceFeedBack(Long orderId, Long workId, HttpServletRequest request) throws OmsBaseException{
        ModelAndView mv = new ModelAndView("work/modify/invoiceFeedBack");
        try{
            mv.addObject("orderId", String.valueOf(orderId));
            mv.addObject("workId", String.valueOf(workId));
            logger.info("发票反馈[BFM-FINANCE] {}", ((KvModel) request.getSession().getAttribute("BFM-FINANCE")).getValue());
        } catch (Exception ex){

        }
        return mv;
    }

    /**
     * 开发票
     */
    @RequestMapping(value = "/invoice/suggest")
    @ResponseBody
    public ResultDTO invoice(@RequestParam("queryText")String queryText) throws OmsBaseException{
        if (StringUtil.isBlank(queryText)) {
            return ResultDTO.fail("请传递有效的公司名称");
        }
        return ResultDTO.success(orderInvoiceBService.getBuyerTaxNumSuggestList(queryText));
    }

    /**
     * 保存开发票
     */
    @PostMapping(value = "/save/invoice")
    @ResponseBody
    public ResultDTO saveInvoice(@RequestBody @Valid OrderInvoiceDTO orderInvoiceDTO) {
        OperatePermissionVO operatePermission = orderWorkOperatePermissionBService.getOperatePermission(orderInvoiceDTO.getOrderId(), orderInvoiceDTO.getWorkId(), OrderConsts.ORDER_OP_TYPE_INVOICE);
        if (!operatePermission.getCanOperate()) {
            return ResultDTO.fail(operatePermission.getMsg());
        }
        // 设置公司名称
        if (!NumberUtil.isNullOrZero(orderInvoiceDTO.getCompanyId())) {
            ResponseDTO<CompanyDRO> company = companyListRemoteService.getCompanyDROById(orderInvoiceDTO.getCompanyId());
            if (company.isSuccess() && company.getData() != null) {
                orderInvoiceDTO.setCompanyName(company.getData().getFullName());
            }
        }

        orderInvoiceBService.saveInvoice(orderInvoiceDTO);
        return ResultDTO.success();
    }


    /**
     * 推送开票
     */
    @RequestMapping(value = "/invoiceRemind")
    public ModelAndView invoiceRemind(Long orderId, Long workId) throws OmsBaseException{
        ModelAndView mv = new ModelAndView("work/modify/invoiceRemind");

        mv.addObject("orderId", String.valueOf(orderId));
        mv.addObject("workId", String.valueOf(workId));
        return mv;
    }


    /**
     * 推送开票
     */
    @RequestMapping(value = "/save/invoiceRemind")
    @ResponseBody
    public ResultDTO saveInvoiceRemind(@RequestBody @Valid OmsOperator operator) {
        try {
            orderInvoiceBService.invoiceRemind(operator);
        } catch (Exception e) {
            logger.error("推送开票提醒失败", e);
            return ResultDTO.fail("推送开票提醒失败");
        }

        return ResultDTO.success();
    }


    /**
     * 跟单
     */
    /* @RequestMapping(value = "/track")
   public ModelAndView track(Long orderId, Long workId) {

        OrderWork orderWork = orderWorkService.findOrderWorkByKey(orderId, workId);

        // 未完成跟单
        List<OrderTrackVO> unCompleteOrderTrackList = orderTrackBService.listUnCompleteOrderTrackByOrderId(orderId, workId);

        Integer deptId = getDeptId();

        // 正常跟单项
        List<OrderTrackVO> trackTypeList = Lists.newArrayList();
        DocumentaryContentDIO documentaryContentDIO = new DocumentaryContentDIO();
        //TODO liuying
        documentaryContentDIO.setBizType(orderWork.getBizType());
        if (super.isBranchCompany()) {
            // 非总部员工，都按：服务商跟单处理
            documentaryContentDIO.setServiceProviderDocumentarySwitch(GlobalConsts.YES);
        } else {
            documentaryContentDIO.setDocumentaryDepartmentId(deptId);
        }
        documentaryContentDIO.setStatus(GlobalConsts.YES);
        logger.debug("#oms#track 查询跟单项目入参：{}", JSON.toJSONString(documentaryContentDIO));
        ResponseDTO<List<DocumentaryContentDRO>> listResponseDTO = documentaryContentListRemoteService.listByQuery(documentaryContentDIO);
        logger.debug("#oms#track 查询跟单项目出参：{}", JSON.toJSONString(listResponseDTO));
        boolean statusBool = listResponseDTO.isSuccess();
        List<DocumentaryContentDRO> items = listResponseDTO.getData();
        if (statusBool && !CollectionUtils.isEmpty(items)) {
            items.forEach(e -> {
                int level = Optional.ofNullable(e.getDepartmentPriority()).orElse(e.getServiceProviderDocumentaryPriority());
                OrderTrackVO orderTrackVO = OrderTrackVO.builder().mapId(e.getId()).mapName(e.getContent()).level(level).build();
                trackTypeList.add(orderTrackVO);
            });
        }

        // 其他跟单项
        OrderTrackVO otherTrack = OrderTrackVO.builder()
                .level(OrderConsts.ORDER_TRACT_OTHER_TYPE_LEVEL)
                .mapId(OrderConsts.ORDER_TRACT_OTHER_TYPE_ID)
                .build();

        ModelAndView mv = new ModelAndView("work/modify/track");
        mv.addObject("orderWork", orderWork);
        mv.addObject("orderTrackList", unCompleteOrderTrackList);
        mv.addObject("trackTypeList", trackTypeList);
        mv.addObject("otherTrack", otherTrack);
        return mv;
    }*/

    /**
     * 保存跟单
     */
//    @RequestMapping(value = "/save/track")
//    @ResponseBody
//    public ResultDTO saveTrack(@RequestBody OrderTrackDTO orderTrackDTO) throws Exception {
//        OperatePermissionVO operatePermission = orderWorkOperatePermissionBService.getOperatePermission(orderTrackDTO.getOrderId(), orderTrackDTO.getWorkId(), OrderConsts.ORDER_OP_TYPE_TRACK);
//        if (!operatePermission.getCanOperate()) {
//            return ResultDTO.fail(operatePermission.getMsg());
//        }
//
//        orderTrackBService.updateTrack(orderTrackDTO);
//        return ResultDTO.success();
//    }


    /**
     * 跟单
     */
    @RequestMapping(value = "/newtrack")
    public ModelAndView newTrack(Long orderId, Long workId) {

        OrderWork orderWork = orderWorkService.findOrderWorkByKey(orderId, workId);

        ModelAndView mv = new ModelAndView("work/modify/newtrack");
        mv.addObject("orderId", String.valueOf(orderWork.getOrderId()));
        mv.addObject("workId", String.valueOf(orderWork.getWorkId()));
        mv.addObject("bizType", orderWork.getBizType());
        return mv;
    }

    /**
     * 订单抽查
     */
    @RequestMapping(value = "/order/check")
    public ModelAndView check(Long orderId, Long workId) {
        ModelAndView mv = new ModelAndView("work/modify/orderCheck");
        mv.addObject("orderId", String.valueOf(orderId));
        mv.addObject("workId", String.valueOf(workId));
        return mv;
    }


    /**
     * 投诉
     */
    @RequestMapping(value = "/ajax/check/complaint")
    @ResponseBody
    public ResultDTO complaint(Long orderId, Long workId) {

        // 根据订单id查询正在进行中的投诉id
        ResponseDTO<Integer> responseDTO = chsComplainApiListRemoteService.listUnfinishComplainIdByOrderId(orderId);
        if (responseDTO.isSuccess()) {
            if (Objects.equals(responseDTO.getData(), null)){
                return ResultDTO.success(0);
            }
            return ResultDTO.success(responseDTO.getData());
        }
        return ResultDTO.fail(GlobalConsts.FAILD_MSG);
    }

    /**
     * 异常
     */
    @RequestMapping(value = "/ajax/check/abnormal")
    @ResponseBody
    public ResultDTO abnormal(Long orderId, Long workId) {
//        工单若有多个异常，点击跳转至：工单异常列表页，查询对应异常
//        工单若仅：1个异常，点击跳转至：工单异常页 - 异常详情页
//        工单无异常时，分以下两种情况
//        A：当前角色有录入异常权限，则弹框：当前工单无异常，是否确认添加？
//        B：当前角色无录入异常权限，则弹框：当前工单无异常
        ResponseDTO<Integer> responseDTO = abnormalListRemoteService.countAbnormalByOrderId(orderId);
        if (responseDTO.isSuccess()) {
            Integer data = responseDTO.getData();
            return ResultDTO.success(Optional.ofNullable(data).orElse(0));
        }
        return ResultDTO.success();
    }
    /**
     * 非标信息
     */
    @RequestMapping(value = "/nonstandard")
    public ModelAndView nonstandard(Long orderId, Long workId) {

        ModelAndView mv = new ModelAndView("work/modify/nonstandard");
        // 非标信息
        List<OrderNonstandard> orderNonstandardList = orderNonstandardService.listNonstandardByOrderId(orderId);
        // 单独处理图片
        String imageSrc = "";
        List<NonstandardDetailVO> nonstandardDetailVOS = Lists.newArrayList();
        if(CollectionUtils.isNotEmpty(orderNonstandardList)){
            List<OrderNonstandard> imgList = orderNonstandardList.stream().filter(e -> Objects.equals(e.getType(),2)).collect(Collectors.toList());
            List<OrderNonstandard> nonList = orderNonstandardList.stream().filter(e -> Objects.equals(e.getType(),1)).collect(Collectors.toList());
            nonstandardDetailVOS = BeanMapper.mapList(nonList, NonstandardDetailVO.class);
            imageSrc = imgList.size() > 0 ? imgList.get(0).getImageSrc() : "";
        }

        NonstandardVO nonstandardVO = NonstandardVO.builder()
                .imageSrc(imageSrc).orderNonstandardList(nonstandardDetailVOS).orderId(orderId).workId(workId).build();
        mv.addObject("nonstandardVO", nonstandardVO);
        return mv;
    }

    /**
     * 保存非标信息
     */
    @RequestMapping(value = "/save/nonstandard", method = RequestMethod.POST)
    @ResponseBody
    public ResultDTO saveNonstandard(@RequestBody OrderNonstandardDTO orderNonstandardDTO) {

        OperatePermissionVO operatePermission = orderWorkOperatePermissionBService.getOperatePermission(orderNonstandardDTO.getOrderId(),
                orderNonstandardDTO.getWorkId(), OrderConsts.ORDER_OP_TYPE_NONSTANDARD);
        if (!operatePermission.getCanOperate()) {
            return ResultDTO.fail(operatePermission.getMsg());
        }
        orderNonstandardBService.saveOrderNonstandardList(orderNonstandardDTO);

        return ResultDTO.success();

    }

    /**
     * 新机配件信息
     */
    @RequestMapping(value = "/newMachinePart")
    public ModelAndView newMachinePart(Long orderId, Long workId) {

        ModelAndView mv = new ModelAndView("work/modify/newmachinepart");

        // 新机
        List<OrderPostVO> orderPostList = orderWorkOrderPostBService.listOrderPostByOrderId(orderId);
        mv.addObject("orderId", orderId);
        mv.addObject("workId", workId);
        mv.addObject("orderPostList", orderPostList);

        OrderWork orderWork = orderWorkService.findOrderWorkByKey(orderId, workId);
        //厂商单并且业务类型是F
        if (Objects.equals(OrderConsts.ORDER_SOURCE_TYPE_FACTORY, orderWork.getSourceType())
                && Objects.equals(orderWork.getBizType(), com.zmn.consts.GlobalConsts.BIZ_TYPE_F)){

            OrderFactory orderFactory = orderFactoryService.findOrderFactoryByKey(orderId);
            mv.addObject("factoryId", orderFactory.getFactoryId());

            //厂商配件-新件
            List<NewPartVO> newPartVOList = factoryPartBService.listNewPartByOrderIdAndFactoryId(orderId);
            mv.addObject("newPartVOList", newPartVOList);

            //厂商配件-旧件
            List<UsedPartVO> usedPartVOList = factoryPartBService.listUsedPartByOrderIdAndFactoryId(orderId);
            mv.addObject("usedPartVOList", usedPartVOList);
            //邮寄对象
            mv.addObject("postAddressList", OrderFactoryPartConsts.getPostAddressTypeList());
        }

        // 快递公司
        mv.addObject("expressCompanyList", super.listExpressCompany());

        return mv;
    }

    /**
     * 保存新机配件信息
     */
    @RequestMapping(value = "/save/newMachinePart", method = RequestMethod.POST)
    @ResponseBody
    public ResultDTO saveNewMachinePart(@RequestBody OrderNewMachinePartListDTO dto) {

        OperatePermissionVO operatePermission = orderWorkOperatePermissionBService.getOperatePermission(dto.getOrderId(),
                dto.getWorkId(), OrderConsts.ORDER_OP_TYPE_NEW_MACHINE_PART);
        if (!operatePermission.getCanOperate()) {
            return ResultDTO.fail(operatePermission.getMsg());
        }

        try{
            zsNormalOrderPartBService.addNewMachinePartList(dto);
        }catch (OmsBaseException ex) {
            return ResultDTO.fail(ex.getMessage());
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            return ResultDTO.fail(e.getMessage());
        }

        return ResultDTO.success();

    }

    /**
     * 特殊调整
     */
    @RequestMapping(value = "/specialAdjustment.action")
    public ModelAndView specialAdjustment(Long orderId, Long workId) {
        // 该mv只需要传入 moduleId和url即可接入其他服务页面，如果module没有需要添加的，需要手动在SystemConsts、common/zmn.modify.route.js中添加配置
        ModelAndView mv = new ModelAndView("work/modify/embed");

        OrderWork orderWork = orderWorkService.findOrderWorkByKey(orderId, workId);

        mv.addObject("moduleId", SystemConsts.MODULE_ID_ERP);
        if (Objects.equals(orderWork.getType(), OrderConsts.ORDER_TYPE_REFUND)) {
            mv.addObject("url", String.format(EmbedUrlConsts.SPECIAL_ADJUSTMENT, orderWork.getOrderId(), orderWork.getOriginalId(), orderWork.getWorkId()));
        } else {
            boolean isInfoCompany = Objects.equals(orderWork.getManageCompanyType(), CompanyConsts.COMPANY_TYPE_SERVICE_OCO) && Objects.equals(orderWork.getManageCompanyThirdType(), CompanyConsts.COMPANY_TYPE_SERVICE_OCO);

            Integer hasSupervisor = NumberUtil.isNotNullOrZero(orderWork.getMasterSupervisorId()) ? GlobalConsts.YES : GlobalConsts.NO;

            mv.addObject("url", String.format(EmbedUrlConsts.SPECIAL_ADJUSTMENT_NEW, orderWork.getPlatWork(), orderWork.getOrderId(), orderWork.getWorkId(), isInfoCompany ? GlobalConsts.YES : GlobalConsts.NO, hasSupervisor));
        }

        return mv;

    }

    /**
     * 更改分配页面
     * @param orderId
     * @param workId
     * @return
     */
    @RequestMapping(value = "/change/assignment", method = RequestMethod.GET)
    public ModelAndView changeAssignment(Long orderId, Long workId) throws OmsBaseException {
        ModelAndView mv = new ModelAndView("work/modify/changeAssignment");
        OrderWork orderWork = orderWorkService.findOrderWorkByKey(orderId, workId);
        if (!Objects.equals(orderWork.getGrabType(), GlobalConsts.YES)) {
            GrabConfigDTO grabConfigDTO = orderWorkGrabBService.grabConfig(orderWork);
            mv.addObject("grabTime", grabConfigDTO.getGrabTime());
            mv.addObject("agent", grabConfigDTO.getAgent());
            mv.addObject("grabEndTime", DateUtil.dateFormatToString(grabConfigDTO.getGrabEndTime(), DateUtil.FORMAT_DEFAULT));
        }
        mv.addObject("grabType", orderWork.getGrabType());
        mv.addObject("orderId", orderId);
        mv.addObject("workId", workId);
        return mv;
    }

    /**
     * 保存更改分配
     * @param changeAssignmentDTO
     * @param
     * @return
     */
    @RequestMapping(value = "/save/change/assignment", method = RequestMethod.POST)
    @ResponseBody
    public ResultDTO saveChangeAssignment(@RequestBody ChangeAssignmentDTO changeAssignmentDTO) {
        logger.info("【抢单】更改分配入参：【{}】", JSON.toJSONString(changeAssignmentDTO));
        OperatePermissionVO operatePermission = orderWorkOperatePermissionBService.getOperatePermission(changeAssignmentDTO.getOrderId(),
                changeAssignmentDTO.getWorkId(), OrderConsts.ORDER_OP_TYPE_CHANGE_ASSIGNMENT);
        if (!operatePermission.getCanOperate()) {
            return ResultDTO.fail(operatePermission.getMsg());
        }

        try{
            OrderWorkGrabDTO orderWorkGrabDTO = BeanMapper.map(changeAssignmentDTO, OrderWorkGrabDTO.class);
            orderWorkGrabBService.saveGrabType(orderWorkGrabDTO);
        } catch (OmsBaseException ex) {
            return ResultDTO.fail(ex.getMessage());
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            return ResultDTO.fail(e.getMessage());
        }

        return ResultDTO.success();
    }

}